# 变量引用
num = 1
num2 = num
# 查看变量内存地址
print(id(num))
# 内存地址和num相同
print(id(1))
# True
print(id(num2) == id(num))


# 函数参数在传递时是应用传递也就是传递内存地址,而不是实参保存的数值
# 返回值也是引用传递，内存地址相同
def test(grade):
    print("grade的内存地址=%d" % id(grade))
    msg = "hello"
    print("msg的内存地址=%d" % id(msg))
    return msg


age = 10
res = test(age)
print("number的内存地址=%d" % id(age))
print("返回值的内存地址=%d" % id(res))

# 可变类型和不可变类型
# 不可变类型：数字类型、字符串、元组，定义后不能在对变量的内容进行修改
# 可变类型：列表list、字典dict,dict的key必须为不可变类型包含元组
name_dict = {(1,): "fauks"}
print(name_dict[(1,)])

# 全局变量、局部变量
# 全局变量不允许直接修改全局变量，如果要给全局变量赋值，会在函数内部定义一个新的局部变量
score = 99


def demo():
    # 在demo方法中定义新的变量score=199，而不是直接修改外部score
    score = 199
    print(score)


def demo2():
    print(score)


# python为了控制全局变量修改范围，不允许修改全局变量，所以以下两个方法输出不同值
# 199
demo()
# 99
demo2()

# 如果希望在函数内部修改全局变量的值需要使用global声明变量
config = "java"


def change_config():
    """
    先用global声明告诉解释器，变量为全局变量
    :return:
    """
    global config
    config = "python"


print(config)
change_config()
print(config)

# 代码结构：shebang、import、全局变量、函数定义、执行代码
# 全局变量命名规则：添加gl_、g_前缀

# 查看对象中所有的属性和方法
print(dir(change_config()))
print(change_config.__doc__)
